using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;

namespace Hack.Authorization.Core {
	/// <summary>
	/// Generates hashes for strings.
	/// </summary>
	public static class HashGenerator {
		/// <summary>
		/// Empty hash for SHA-1.
		/// </summary>
		public const string EmptyHash1 = "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709";
		/// <summary>
		/// Empty hash for SHA-256.
		/// </summary>
		public const string EmptyHash256 = "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855";
		/// <summary>
		/// Empty hash for SHA-384.
		/// </summary>
		public const string EmptyHash384 = "38B060A751AC96384CD9327EB1B1E36A21FDB71114BE07434C0CC7BF63F6E1DA274EDEBFE76F65FBD51AD2F14898B95B";
		/// <summary>
		/// Empty hash for SHA-512.
		/// </summary>
		public const string EmptyHash512 = "CF83E1357EEFB8BDF1542850D66D8007D620E4050B5715DC83F4A921D36CE9CE47D0D13C5D85F2B0FF8318D2877EEC2F63B931BD47417A81A538327AF927DA3E";

		/// <summary>
		/// Generates a hash with 512 bytes strength.
		/// </summary>
		/// <param name="source">Source string.</param>
		/// <returns>Returns the array of bytes.</returns>
		public static byte[] GenerateHash(string source) {
			return GenerateHash(source, HashStrength._512);
		}
		/// <summary>
		/// Generates a hash with the given strength.
		/// </summary>
		/// <param name="source">Source string.</param>
		/// <param name="strength">Hash strength.</param>
		/// <returns>Returns the array of bytes.</returns>
		public static byte[] GenerateHash(string source, HashStrength strength) {
			switch (strength) {
				case HashStrength._1: {
						SHA1Managed hasher = new SHA1Managed();
						return hasher.ComputeHash(Encoding.UTF8.GetBytes(source));
					}
				case HashStrength._256: {
						SHA256Managed hasher = new SHA256Managed();
						return hasher.ComputeHash(Encoding.UTF8.GetBytes(source));
					}
				case HashStrength._384: {
						SHA384Managed hasher = new SHA384Managed();
						return hasher.ComputeHash(Encoding.UTF8.GetBytes(source));
					}
				default: {
						SHA512Managed hasher = new SHA512Managed();
						return hasher.ComputeHash(Encoding.UTF8.GetBytes(source));
					}
			}
		}

		/// <summary>
		/// Converts a hash to a hex-based string.
		/// </summary>
		/// <param name="hash">Hash to be converted.</param>
		/// <returns>Returns the hash as string.</returns>
		public static string HashToString(byte[] hash) {
			int i;
			StringBuilder sOutput = new StringBuilder(hash.Length);
			for (i = 0; i < hash.Length; i++) {
				sOutput.Append(hash[i].ToString("X2"));
			}
			return sOutput.ToString();
		}
	}
}
